#!/usr/bin/python
# coding:utf-8

"""
@author: 信长华
@contact: skywater@gmail.com
@software: PyCharm
@file: user.py
@time: 2021/7/30 15:21
"""
from datetime import timedelta
from typing import Any, Optional

from fastapi import APIRouter, Header

from ..common.api_response import ResponseEnum, ApiResponse
from ..common.constant import USERNAME_DICT
from ..common.security import check_jwt_token, create_access_token
from ..core.api_route import TimedRoute
from ..file_logger import logger
from ..model.model import UserAO, SysUser
from ..service.user_service import authenticate_user, get_current_user
from ..settings import settings

router = APIRouter(route_class=TimedRoute)


@router.post("/login")
async def login_for_access_token(user_info: UserAO):
    user: SysUser = authenticate_user(
        USERNAME_DICT, user_info.username, user_info.password
    )
    if not user:
        logger.info(
            f"用户邮箱认证错误: email{user_info.username} password:{user_info.password}"
        )
        return ApiResponse.build_error(response_enum=ResponseEnum.PASSWORD_ERROR)
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)

    # 登录token 存储了user.id 和 username
    return ApiResponse.build_success(
        data={
            "token": create_access_token(
                user.username, str(user.id), expires_delta=access_token_expires
            ),
        }
    )


@router.get("/user/info", summary="获取用户信息", name="获取用户信息", description="此API没有验证权限")
async def get_user_info(
    token: Optional[str] = Header(..., description="登录token", convert_underscores=True)
) -> Any:
    """
    Header是
    *和...的说明 https://www.jianshu.com/p/c213e566229d
    *,  函数中的星号表示后面的参数必须通过关键字参数的方式传入
    Header中第一个参数是默认值，为 None 代表默认值为空，如果为 ... 则表示为必填
    获取用户信息
    Header是Query、Path、Cookie的姐妹类，它们都继承自Param类。也就是参数验证类
    自动获取, header中的一个参数
    :return:
    """
    if not token:
        return ApiResponse.build_error(response_enum=ResponseEnum.TOKEN_ERROR)
    token_dict = check_jwt_token(token)
    username = token_dict.get("subject")
    if not username:
        return ApiResponse.build_error(response_enum=ResponseEnum.TOKEN_ERROR)
    current_user: SysUser = get_current_user(username=username)
    if "admin" not in current_user.role:
        return ApiResponse.build_error(response_enum=ResponseEnum.AUTHORIZATION_ERROR)
    logger.info({"op": "LogUser", "user": current_user})
    return ApiResponse.build_success(data=current_user.dict())
